package com.weilele.leisure.time.ui.view.video

import android.app.Activity
import android.content.Context
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import com.weilele.leisure.time.R
import com.weilele.leisure.time.databinding.PlayerVideoViewBinding
import com.weilele.mvvm.base.livedata.appCompatActivity
import com.weilele.mvvm.utils.activity.*
import com.weilele.mvvm.utils.android_r.fullScreen
import com.weilele.mvvm.utils.android_r.isPortraitScreen
import com.weilele.mvvm.utils.safeGet
import com.yizisu.playerlibrary.IYzsPlayer
import com.yizisu.playerlibrary.view.video_view.helper.IPlayerConfig
import com.yizisu.playerlibrary.view.video_view.helper.IPlayerHelper
import com.yizisu.playerlibrary.view.video_view.helper.PlayerControllerBarHelper
import com.yizisu.playerlibrary.view.video_view.view.BasePlayerRootView

class PlayerVideoView : BasePlayerRootView, IPlayerHelper {
    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    private val videoViewBinding by lazy {
        PlayerVideoViewBinding.inflate(
            LayoutInflater.from(context),
            this,
            true
        )
    }

    init {
        videoViewBinding.smallPlayPause.enableGoneWhenPlaying = false
    }

    private var playerConfig: IPlayerConfig? = null

    override fun onAttachPlayerConfig(playerConfig: IPlayerConfig) {
        super.onAttachPlayerConfig(playerConfig)
        this.playerConfig = playerConfig
        playerConfig.clickBackData.observeForever(::onClickBack)
        playerConfig.fullScreenChangeData.observeForever(::onFullScreen)
        playerConfig.showOrHideControllerData.observeForever(::onShowOrHideBar)
    }

    override fun onDetachedPlayerConfig(playerConfig: IPlayerConfig) {
        super.onDetachedPlayerConfig(playerConfig)
        playerConfig.clickBackData.removeObserver(::onClickBack)
        playerConfig.showOrHideControllerData.removeObserver(::onShowOrHideBar)
        playerConfig.fullScreenChangeData.removeObserver(::onFullScreen)
    }

    /**
     * 展示或者隐藏导航栏
     */
    private fun onShowOrHideBar(data: Float?) {
        data?.let {
            //region 隐藏或者显示底部导航栏
            if (it != 0f) {
                videoViewBinding.bottomView.visibility = View.VISIBLE
                videoViewBinding.topBar.visibility = View.VISIBLE
                videoViewBinding.lockView.visibility = View.VISIBLE
            } else {
                videoViewBinding.bottomView.visibility = View.INVISIBLE
                videoViewBinding.topBar.visibility = View.INVISIBLE
                videoViewBinding.lockView.visibility = View.INVISIBLE
            }
            val offYBottom = videoViewBinding.bottomView.height * (1 - it)
            val offYTop = -videoViewBinding.bottomView.height * (1 - it)
            if (videoViewBinding.bottomView.height == 0) {
                post {
                    videoViewBinding.bottomView.translationY = offYBottom
                    videoViewBinding.topBar.translationY = offYTop
                }
            } else {
                videoViewBinding.bottomView.translationY = offYBottom
                videoViewBinding.topBar.translationY = offYTop
            }
            //endregion
        }
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        checkScreenLock(ev)
        return super.onInterceptTouchEvent(ev)
    }

    /**
     * 检测屏幕是否可用
     */
    private fun checkScreenLock(ev: MotionEvent?) {
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {
                playerConfig?.playerControllerBarHelperData?.value?.hideIfShow(
                    PlayerControllerBarHelper.DEFAULT_DELAY_DURATION
                )
                if (playerConfig?.screenNotLockData?.value == false) {
                    videoViewBinding.lockView.postHideWhenLock()
                }
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                if (playerConfig?.fullScreenChangeData?.value == true) {
                    (context as Activity).window.fullScreen(true)
                }
            }
        }
    }

    override fun onConfigurationChanged(newConfig: Configuration?) {
        super.onConfigurationChanged(newConfig)
        val displayMetrics = resources.displayMetrics
        val margin = if (displayMetrics.widthPixels <= displayMetrics.heightPixels) {
            videoViewBinding.backView.visible()
            videoViewBinding.topBarBackView.invisible()
            0
        } else {
            videoViewBinding.topBarBackView.visible()
            videoViewBinding.backView.invisible()
            dip(32)
        }
        videoViewBinding.topBar.setPadding(
            margin,
            videoViewBinding.topBar.paddingTop,
            margin,
            videoViewBinding.topBar.paddingBottom
        )
        videoViewBinding.bottomView.setPadding(
            margin,
            videoViewBinding.bottomView.paddingTop,
            margin,
            videoViewBinding.bottomView.paddingBottom
        )
    }

    fun onClickBack(view: View?) {
        if (playerConfig?.fullScreenChangeData?.value == true) {
            playerConfig?.updateFullScreenChange(false)
            return
        }
        (context as Activity).finishAfterTransition()
    }

    override fun onPlayerListChange(playerModels: List<IYzsPlayer.Model>) {
        super.onPlayerListChange(playerModels)
        checkIsShowView()
    }

    private fun checkIsShowView() {
        val player = playerConfig?.player ?: return
        val playerModels = player.getAllPlayModel()
        if (playerModels.isEmpty() || playerModels.count() == 1 || playerConfig?.fullScreenChangeData?.value != true) {
            videoViewBinding.nextView.visibility = View.GONE
            videoViewBinding.preView.visibility = View.GONE
            videoViewBinding.selectListText.visibility = View.GONE
        } else {
            videoViewBinding.nextView.visibility = View.VISIBLE
            videoViewBinding.preView.visibility = View.VISIBLE
            videoViewBinding.selectListText.visibility = View.VISIBLE
        }
    }

    /**
     * 全屏与非全屏切换
     */
    private fun onFullScreen(full: Boolean?) {
        checkIsShowView()
        updateLayoutParams(full ?: false)
    }

    override fun onVideoSizeChange(
        width: Int,
        height: Int,
        unappliedRotationDegrees: Int,
        pixelWidthHeightRatio: Float,
        playerModel: IYzsPlayer.Model?
    ) {
        super.onVideoSizeChange(
            width,
            height,
            unappliedRotationDegrees,
            pixelWidthHeightRatio,
            playerModel
        )
        if (playerConfig?.fullScreenChangeData?.value == true) {
            //目前是全屏状态
            if (width <= height) {
                getActivity()?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            } else {
                getActivity()?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            }
        }
    }


    /**
     * 横竖屏改变，更改参数
     */
    private fun updateLayoutParams(full: Boolean) {
        val view = this.parent.safeGet<View>() ?: return
        val lp = view.layoutParams
        if (!full) {
            lp.height = getResDimensionPixelSize(R.dimen.video_default_height)
        } else {
            lp.height = ViewGroup.LayoutParams.MATCH_PARENT
        }
        view.layoutParams = lp
        playerConfig?.player?.getCurrentModel()?.let {
            if (full && it.videoHeight <= it.videoWidth) {
                getActivity()?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            } else {
                getActivity()?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            }
        }
    }

    override fun isNeedPlayerListener(): Boolean {
        return true
    }

}